<template>
	<!-- 虚拟滚动 -->
    <div style='width:100%;height:100%'>
        <template v-if='virtual'>
            <div name='虚拟滚动盒子' ref='scroll' @scroll='scrollEvent($event)' style='width:100%;height:100%;position:relative;overflow: auto;-webkit-overflow-scrolling: touch'>
                <div name='占位盒子' :style="{ height: listHeight  + 'px', position:'absolute', left:0, top:0,right:0,zIndex:-1 }"></div>
                <div name='计算内容盒子' :style="{ transform: getTransform, position:'absolute', left:0, top:0,right:0 }">
                    <slot :data='visibleData'></slot>
                </div>
            </div>
        </template>
        <template v-else>
            <slot :data='data'></slot>
        </template>
    </div>
</template>

<script>
	export default {
		props:{
			data:{ type: Array, default: ()=> [] },
            rowHeight: { type: Number, default: 32 },
            virtual: { type: Boolean, default: false },
		},
        data(){
            return {
                screenHeight: 0,    // 可视区域高度
                startOffset: 0,     // 偏移量
                start: 0,           // 起始索引
                end:null,           // 结束索引
            }
        },
        mounted(){
            if(this.virtual){
                setTimeout(()=>{
                    this.init()
                    window.onresize = ()=>{
                        this.init()
                    }
                },100)
            }
        },
        methods:{
            // 初始化
            init(){
                // 页面数据初始化
                this.screenHeight = this.$refs.scroll.clientHeight
                this.start = 0
                // 这里的截取结束位置需要根据开始位置和首屏显示的条数来确定
                this.end = this.start + this.visibleCount
            },
            // 监听滚动
            scrollEvent () {
                let scrollTop = this.$refs.scroll.scrollTop // 当前滚动位置
                this.start = Math.floor(scrollTop / this.rowHeight)   // 此时的开始索引
                this.end = this.start + this.visibleCount  // 此时的结束索引
                this.startOffset = scrollTop - (scrollTop % this.rowHeight) // 滚动时列表盒子的偏移量
            },
            getData(){
                return this.data.slice(this.start, Math.min(this.end, this.data.length))
            }
        },
        computed:{
            // 列表总高度
            listHeight () {
              return this.data.length * this.rowHeight;
            },
            // 可显示的列表项数
            visibleCount () {
              return Math.ceil(this.screenHeight / this.rowHeight)
            },
            // 偏移量对应的style
            getTransform () {
              return `translate3d(0, ${this.startOffset}px, 0)`
            },
            // 获取真实显示列表数据
            visibleData() {
                if(Array.isArray(this.data) && this.data.length > 0){
                     return  this.data.slice(this.start, Math.min(this.end, this.data.length))
                }else{
                    return []
                }
            }
        },
	}
</script>
